using System;
using System.Collections.Generic;
using System.Configuration;
using System.Configuration.Provider;
using System.Web.Configuration;
using System.Web;
using NiSis.Entities;
using NiSis.Data;
using NiSis.Data.Bases;
using System.Reflection;
using System.Text;

namespace NiSis.Data
{
    /// <summary>
    /// Custum Ecm Utilities Adding extra capabilities to data repository layer
    /// </summary>
    public class CustomUtil
    {
        /// <summary>
        /// Performs a select disticnt like query over a generic tlist
        /// </summary>
        /// <typeparam name="T">List Type</typeparam>
        /// <param name="originalList">Original List object</param>
        /// <param name="distinctProperties">properties on wich the distinct query will be performed</param>
        /// <returns></returns>
        public static TList<T> SelectDistinctFromList<T>(TList<T> originalList, System.Enum[] distinctProperties) where T : IEntity, new()
        {
            Type instanceType = originalList.GetType().GetGenericArguments()[0].BaseType;

            PropertyInfo[] propertyColumns = new PropertyInfo[distinctProperties.Length];
            for (int i = 0; i < distinctProperties.Length; i++)
            {
                propertyColumns[i] = instanceType.GetProperty(distinctProperties[i].ToString());
            }

            TList<T> resultList = new TList<T>();
            System.Collections.Specialized.StringCollection keys = new System.Collections.Specialized.StringCollection();
            foreach (T instance in originalList)
            {
                string key = string.Empty;
                foreach (PropertyInfo pi in propertyColumns)
                {
                    key += pi.GetValue(instance, null) + "|";
                }
                if (!keys.Contains(key))
                {
                    keys.Add(key);
                    resultList.Add(instance);
                }
            }
            return resultList;
        }
        /// <summary>
        /// Performs a select disticnt like query over a generic tlist
        /// </summary>
        /// <typeparam name="T">List Type</typeparam>
        /// <param name="originalList">Original List object</param>
        /// <param name="distinctProperties">properties on wich the distinct query will be performed</param>
        /// <returns></returns>
        public static VList<T> SelectDistinctFromVList<T>(VList<T> originalList, System.Enum[] distinctProperties)
        {
            if (originalList.Count==0)
                return originalList;

            Type instanceType = originalList.GetType().GetGenericArguments()[0].BaseType;
            
            if (instanceType == null)
                instanceType = originalList[0].GetType();

            PropertyInfo[] propertyColumns = new PropertyInfo[distinctProperties.Length];
            for (int i = 0; i < distinctProperties.Length; i++)
            {
                propertyColumns[i] = instanceType.GetProperty(distinctProperties[i].ToString());
            }

            VList<T> resultList = new VList<T>();
            System.Collections.Specialized.StringCollection keys = new System.Collections.Specialized.StringCollection();
            foreach (T instance in originalList)
            {
                StringBuilder keyBuilder = new StringBuilder();
                foreach (PropertyInfo pi in propertyColumns)
                {
                    keyBuilder.AppendFormat("{0}|", pi.GetValue(instance, null));
                }
                if (!keys.Contains(keyBuilder.ToString()))
                {
                    keys.Add(keyBuilder.ToString());
                    resultList.Add(instance);
                }
            }
            return resultList;
        }
        /// <summary>
        /// Get global state of utenze, if only one is different returns non ipotizzato
        /// </summary>
        /// <returns></returns>
        public static SshStatoRelazioniList GetState(VList<VSimpleTraderPrec> traders)
        {
            if (traders.Count==0)
                return SshStatoRelazioniList.NonIpotizzato;
            if (traders.Count==1)
                return GetState(traders[0]);

            SshStatoRelazioniList stPrec = GetState(traders[0]);
            foreach (VSimpleTraderPrec tp in traders)
                if (GetState(tp) != stPrec)
                    return SshStatoRelazioniList.NonIpotizzato;

            return stPrec;
        }
        public static VList<VTpUtenzeStorico> GetUsersForTrader(string CdPool, string CdTraderPrec,string cdMese,SshStatoRelazioniList state)
        {
            VList<VTpUtenzeStorico> ut = DataRepository.VTpUtenzeStoricoProvider.Get(
                string.Format("cd_pool='{0}' and cd_storico_mensile_rete='{1}' and cd_trader_precedente='{2}' and Id_Stato_Lavorazione_utenza={3}",
                CdPool, cdMese, CdTraderPrec,(int) state), string.Empty);

            return ut;

        }
        public static SshStatoRelazioniList GetState(VSimpleTraderPrec trader)
        {
            VList<VTpUtenzeStorico> ut=DataRepository.VTpUtenzeStoricoProvider.Get(string.Format("cd_pool='{0}' and cd_storico_mensile_rete='{1}' and cd_trader_precedente='{2}'",trader.CdPool,trader.CdStoricoMensileRete,trader.CdSocieta),"cd_cliente");
            if (ut.Count==0)
                return SshStatoRelazioniList.NonIpotizzato;
            
            int sPrec = (ut[0].IdStatoLavorazioneUtenza??0);

            VList<VTputenzePool> utp=DataRepository.VTputenzePoolProvider.Get(
                string.Format("cd_pool='{0}' and cd_storico_mensile_rete='{1}' and cd_trader_precedente='{2}'",trader.CdPool,trader.CdStoricoMensileRete,trader.CdSocieta),"cd_cliente");
            //utp=CustomUtil.SelectDistinctFromVList<VTputenzePool>(utp,new Enum[] 
            //        {VTputenzePoolColumn.CdCliente,VTputenzePoolColumn.
            if (utp.Count>ut.Count)
                return SshStatoRelazioniList.NonIpotizzato;
            
            foreach (VTpUtenzeStorico us in ut)
                if ((us.IdStatoLavorazioneUtenza ??0)!=sPrec)
                    return SshStatoRelazioniList.NonIpotizzato;
            return (SshStatoRelazioniList)sPrec;

        }
        public static SshStatoRelazioniList GetState2(VSimpleTraderPrec trader)
        {
            VList<VTpUtenzeStorico> ut = DataRepository.VTpUtenzeStoricoProvider.Get(string.Format("cd_pool='{0}' and cd_storico_mensile_rete='{1}' and cd_trader_precedente='{2}'", trader.CdPool, trader.CdStoricoMensileRete, trader.CdSocieta), "cd_cliente");
            if (ut.Count == 0)
                return SshStatoRelazioniList.NonIpotizzato;

            int sPrec = (ut[0].IdStatoLavorazioneUtenza ?? 0);

            VList<VTputenzePool> utp = DataRepository.VTputenzePoolProvider.Get(
                string.Format("cd_pool='{0}' and cd_storico_mensile_rete='{1}' and cd_trader_precedente='{2}'", trader.CdPool, trader.CdStoricoMensileRete, trader.CdSocieta), "cd_cliente");
            if (utp.Count > ut.Count)
                return SshStatoRelazioniList.NonIpotizzato;

            foreach (VTpUtenzeStorico us in ut)
                if ((us.IdStatoLavorazioneUtenza ?? 0) != sPrec)
                    sPrec = (us.IdStatoLavorazioneUtenza ?? 0);

            return (SshStatoRelazioniList)sPrec;

        }
        public static VList<IShipperTraderPool> SelectDistinctFromIShipperTraderPool(VList<IShipperTraderPool> inputList)
        {
            System.Collections.Specialized.StringCollection keys = new System.Collections.Specialized.StringCollection();
            VList<IShipperTraderPool> newList = new VList<IShipperTraderPool>();

            foreach (IShipperTraderPool newItem in inputList)
            {
                if (! keys.Contains(newItem.DsSocieta))
                {
                    keys.Add(newItem.DsSocieta);
                    newList.Add(newItem);
                }
            }
            return newList;
        }
        public static string DataInverter(string oldDt)
        {
            try
            {
                return String.Format("{0}{1}", oldDt.Substring(4, 2), oldDt.Substring(0,4));
            }
            catch
            {
                return oldDt;
            }
        }

        public static string CdMeseFromNow()
        {
            string result =DateTime.Now.Year.ToString()+ DateTime.Now.Month.ToString();
            return result;
        }
        public static string LinearizeTp(VList<VTradersPrec> tPlist)
        {
            string results = string.Empty;

            foreach (VTradersPrec tp in tPlist)
                results += tp.CdTraderPrecedente + ",";

            results= results.TrimEnd(',');
            results =string.Format("'{0}'", results.Replace(",","','"));
            return results;
        }

        public static string LinearizeUsers(VList<VTradersPrec> tPlist)
        {
            string results = string.Empty;

            foreach (VTradersPrec tp in tPlist)
                if (! string.IsNullOrEmpty(tp.CdCliente))
                    results += tp.CdCliente + ",";

            if (results == string.Empty)
                return string.Empty;

            results = results.TrimEnd(',');
            results = string.Format("'{0}'", results.Replace(",", "','"));
            return results;
        }

        public static string LinearizeCdPuntoFornitura(VList<VTradersPrec> tPlist)
        {
            string results = string.Empty;

            foreach (VTradersPrec tp in tPlist)
                if (!string.IsNullOrEmpty(tp.CdCliente))
                    results += tp.CdPuntoFornitura + ",";

            if (results == string.Empty)
                return string.Empty;

            results = results.TrimEnd(',');
            results = string.Format("'{0}'", results.Replace(",", "','"));
            return results;
        }

        public static string GetMonthFromWhereString(string sWhere, string sPrefix)
        {

            try
            {
                if (!sWhere.ToUpper().Contains("CD_STORICO_MENSILE_RETE='"))
                    return string.Empty;

                sWhere = sWhere.ToUpper();
                string result = sWhere.Substring(sWhere.IndexOf("CD_STORICO_MENSILE_RETE='"), sWhere.IndexOf("CD_STORICO_MENSILE_RETE='") + 32);
                result = string.Format("{0} {1}", sPrefix, result);
                return result;
            }
            catch (Exception)
            {
                return string.Empty;
                
            }
        }
        public static void UpdatePoolStateAll()
        {
            //TList<SshPool> pools = DataRepository.SshPoolProvider.GetAll();
            VList<VPool> vpools = DataRepository.VPoolProvider.GetAll();
            foreach (VPool pool in vpools)
            {
                UpdatePoolState(pool);
            }
        }
        public static void UpdatePoolStateAll(string cdMese)
        {
            //TList<SshPool> pools = DataRepository.SshPoolProvider.Find(
            //    string.Format("cd_storico_mensile_rete='{0}'", cdMese));

            VList<VPool> vpools = DataRepository.VPoolProvider.Get(
                string.Format("cd_mese_inizio_fornitura='{0}'", cdMese),string.Empty);

            foreach (VPool pool in vpools)
            {
                UpdatePoolState(pool);
            }
        }
        public static void UpdatePoolStateAllLavorati(string cdMese)
        {
            //TList<SshPool> pools = DataRepository.SshPoolProvider.Find(
            //    string.Format("cd_storico_mensile_rete='{0}'", cdMese));

            VList<VPool> vpools = DataRepository.VPoolProvider.Get(
                string.Format("cd_mese_inizio_fornitura='{0}' and id_stato<>0", cdMese), string.Empty);

            foreach (VPool pool in vpools)
            {
                UpdatePoolState(pool);
            }
        }


        public static void UpdatePoolState(VPool pool)
        {
            SshStatoRelazioniList st = DataRepositoryUtils.PoolState(pool.CdPool, pool.CdMeseInizioFornitura);
            SshPoolState pState = DataRepository.SshPoolStateProvider.GetByCdPoolCdStoricoMensileReteCdComune(
                    pool.CdPool,pool.CdMeseInizioFornitura,pool.CdComune) ?? new SshPoolState();
              
            pState.CdPool = pool.CdPool;
            pState.CdStoricoMensileRete = pool.CdMeseInizioFornitura;
            pState.CdComune = pool.CdComune;
            pState.IdStatoRelazione = (int)st;
            if (pState.IdStatoRelazione!=0 || ! pState.IsNew)
                DataRepository.SshPoolStateProvider.Save(pState);
        }
        public static void UpdatePoolState(string cdPool,string cdMese)
        {
            VList<VPool> vpools = DataRepository.VPoolProvider.Get(
                string.Format("cd_pool='{0}' and cd_mese_inizio_fornitura='{1}'", cdPool, cdMese),string.Empty);

            foreach (VPool pool in vpools)
            {
                UpdatePoolState(pool);
            }
            //int count;
            //TList<SshPool> pools = DataRepository.SshPoolProvider.GetByCdStoricoMensileReteCdPoolCdComune(
            //    string.Format("cd_pool='{0}' and cd_storico_mensile_rete='{1}'", cdPool, cdMese));
    
            //foreach(SshPool pool in pools)
                

        }
      

    }
}

